package com.micromall.service.strategy.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.micromall.common.exception.BusiException;
import com.micromall.common.utils.Dict;
import com.micromall.common.utils.StringUtils;
import com.micromall.model.BusiOrder;
import com.micromall.service.IBusiOrderService;
import com.micromall.service.strategy.IDiscountStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单总额折扣实现类.
 * Created by DanteFung on 2017/8/7.
 */
@Service
public class OrderTotalAmountDiscountStrategyImpl implements IDiscountStrategy{

    private static final Logger logger = LoggerFactory.getLogger(OrderTotalAmountDiscountStrategyImpl.class);

    private static final int LESS_THAN = -1;
    private static final int EQUAL = 0;
    private static final int MORE_THAN = 1;


    @Autowired
    private IBusiOrderService busiOrderService;

    @Override
    public Map doDiscount(String memberNo, String totalAmount) {
        Map mapdto = new HashMap();
        StringBuilder errorMessage = new StringBuilder();
        if (StringUtils.isBlank(memberNo)) {
            errorMessage.append("会员编号不能为空!");
        }
        if (StringUtils.isBlank(totalAmount)) {
            errorMessage.append("订单总金额不能为空!");
        }
        if (StringUtils.isNotBlank(errorMessage.toString())) {
            throw new BusiException(String.format("业务异常:[%s]", errorMessage.toString()));
        }
        // 1、查询该会员所有已支付的订单.
        String discountPrice = null;
        String disType = null;
        EntityWrapper<BusiOrder> ew = new EntityWrapper<>();
        BusiOrder busiOrderQuery = new BusiOrder();
        busiOrderQuery.setMemberNo(memberNo);
        busiOrderQuery.setPayStatus(Dict.BusiOrder.PayStatus.PAYED.getCode());
        ew.setEntity(busiOrderQuery);
        List<BusiOrder> busiOrders = busiOrderService.selectList(ew);
        if (null != busiOrders && !busiOrders.isEmpty()) {
            // 这里包含两种:1、第一次累计，原价累计； 2、有折扣金额累计.
            BigDecimal sum = new BigDecimal(0);
            for (BusiOrder busiOrder : busiOrders) {
                String disPrice = busiOrder.getStandy1();
                if (StringUtils.isBlank(disPrice)) {
                    disPrice = "0";
                }
                BigDecimal disPriceBigDecimal = new BigDecimal(disPrice);
                sum = sum.add(disPriceBigDecimal);
            }
            // 判断满足哪种折扣类别.
            // -1 : <
            // 0: =
            // 1: >
            BigDecimal discount = judgeWhichDiscount(sum);
            disType = judgeWhichDisType(discount);
            discountPrice = discount.multiply(new BigDecimal(totalAmount)).toString();
        } else { // 第一次无订单.
            // do nothing ...
            if (logger.isDebugEnabled()) {
                logger.info("会员[{}]第一次无任何订单...", memberNo);
            }
            discountPrice = new BigDecimal(1).multiply(new BigDecimal(totalAmount)).toString();
        }
        if (logger.isDebugEnabled()) {
            logger.info("会员编号[{}]-订单原始金额[{}]-订单折扣价[{}]-订单折扣类型[{}]", memberNo, totalAmount, discountPrice, disType);
        }
        mapdto.put("discountPrice", discountPrice);
        mapdto.put("disType", disType);
        return mapdto;
    }

    private BigDecimal judgeWhichDiscount(BigDecimal sum){
//        BigDecimal sum = new BigDecimal(1499.199);
        BigDecimal d500 = new BigDecimal(500);
        BigDecimal d1500 = new BigDecimal(1500);
        BigDecimal d3500 = new BigDecimal(3500);
        BigDecimal d7000 = new BigDecimal(7000);
        BigDecimal d15000 = new BigDecimal(15000);
        BigDecimal d30000 = new BigDecimal(30000);
        if (d500.compareTo(sum) == EQUAL
                || (d500.compareTo(sum) == LESS_THAN && d1500.compareTo(sum) == MORE_THAN)) {
            // 0.95
            logger.info("(DIS01)[500, 1500) 9.5折");
            return new BigDecimal(0.95);
        } else if (d1500.compareTo(sum) == EQUAL
                || (d1500.compareTo(sum) == LESS_THAN && d3500.compareTo(sum) == MORE_THAN)) {
            // 0.9
            logger.info("(DIS02)[1500, 3500) 9折");
            return new BigDecimal(0.9);

        } else if (d3500.compareTo(sum) == EQUAL
                || (d3500.compareTo(sum) == LESS_THAN && d7000.compareTo(sum) == MORE_THAN)) {
            // 0.85
            logger.info("(DIS03)[3500, 7000) 8.5折");
            return new BigDecimal(0.85);
        } else if (d7000.compareTo(sum) == EQUAL
                || (d7000.compareTo(sum) == LESS_THAN && d15000.compareTo(sum) == MORE_THAN)) {
            // 0.8
            logger.info("(DIS04)[7000, 14999) 8折");
            return new BigDecimal(0.8);
        } else if (d15000.compareTo(sum) == EQUAL
                || (d15000.compareTo(sum) == LESS_THAN && d30000.compareTo(sum) == MORE_THAN)) {
            // 0.75
            logger.info("(DIS05)[15000, 30000) 7.5折;");
            return new BigDecimal(0.75);
        } else if (d30000.compareTo(sum) == EQUAL
                || d30000.compareTo(sum) == LESS_THAN) {
            // 0.7
            logger.info("(DIS06)>=30000 7折");
            return new BigDecimal(0.7);
        }

        return new BigDecimal(1);// 都不满足就原价
    }

    private String judgeWhichDisType(BigDecimal discount){
        if (new BigDecimal(0.95).compareTo(discount) == EQUAL) {
            return Dict.BusiOrder.DISCOUNT_TYPE.DIS01.getCode();
        } else if (new BigDecimal(0.9).compareTo(discount) == EQUAL) {
            return Dict.BusiOrder.DISCOUNT_TYPE.DIS02.getCode();
        } else if (new BigDecimal(0.85).compareTo(discount) == EQUAL) {
            return Dict.BusiOrder.DISCOUNT_TYPE.DIS03.getCode();
        } else if (new BigDecimal(0.8).compareTo(discount) == EQUAL) {
            return Dict.BusiOrder.DISCOUNT_TYPE.DIS04.getCode();
        } else if (new BigDecimal(0.75).compareTo(discount) == EQUAL) {
            return Dict.BusiOrder.DISCOUNT_TYPE.DIS05.getCode();
        } else if (new BigDecimal(0.7).compareTo(discount) == EQUAL) {
            return Dict.BusiOrder.DISCOUNT_TYPE.DIS06.getCode();
        }
        return null;
    }
}
